package sk.fhi.client.presenter;

import net.customware.gwt.dispatch.client.DispatchAsync;
import net.customware.gwt.presenter.client.EventBus;
import net.customware.gwt.presenter.client.place.Place;
import net.customware.gwt.presenter.client.place.PlaceRequest;
import net.customware.gwt.presenter.client.widget.WidgetDisplay;
import sk.fhi.client.event.CancelEditEvent;
import sk.fhi.client.event.UpdateEvent;
import sk.fhi.shared.model.Contact;
import sk.fhi.shared.rpc.action.GetAction;
import sk.fhi.shared.rpc.action.SaveAction;
import sk.fhi.shared.rpc.result.GetResult;
import sk.fhi.shared.rpc.result.SaveResult;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.inject.Inject;

public class EditContactPresenter extends
		BasePresenter<EditContactPresenter.Display> {

	public interface Display extends WidgetDisplay {
		HasClickHandlers getSaveButton();

		HasClickHandlers getCancelButton();

		HasValue<String> getFirstName();

		HasValue<String> getLastName();

		HasValue<String> getEmailAddress();
	}

	private Contact contact;
	public static final Place PLACE = new Place("ContactsEdit");

	@Inject
	public EditContactPresenter(Display display, EventBus eventBus,
			DispatchAsync dispatcher) {
		super(display, eventBus, dispatcher);
		bind();
	}

	@Override
	protected void onBind() {
		
		this.display.getSaveButton().addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				doSave();
			}
		});

		this.display.getCancelButton().addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				contact = null;
				eventBus.fireEvent(new CancelEditEvent());
			}
		});

	}

	protected void doSave() {
		if (contact == null)
			contact = new Contact();

		contact.setFirstName(display.getFirstName().getValue());
		contact.setLastName(display.getLastName().getValue());
		contact.setEmailAddress(display.getEmailAddress().getValue());

		//update
		if (contact.getId() != null) {
			dispatcher.execute(new SaveAction(contact),
					new AsyncCallback<SaveResult>() {
						public void onFailure(Throwable caught) {
							Window.alert("Error updating contact");
						}

						@Override
						public void onSuccess(SaveResult arg0) {
							eventBus.fireEvent(new UpdateEvent(arg0
									.getEntity()));
						}
					});
		//save
		} else {
			dispatcher.execute(new SaveAction(contact),
					new AsyncCallback<SaveResult>() {

						public void onFailure(Throwable caught) {
							caught.printStackTrace();
							Window.alert("Error Adding contact");
						}

						@Override
						public void onSuccess(SaveResult arg0) {
							eventBus.fireEvent(new UpdateEvent(arg0
									.getEntity()));
						}
					});
		}

		contact = null;
	}

	private void getContact(String id) {
		dispatcher.execute(new GetAction(new Contact(), new Long(id)),
				new AsyncCallback<GetResult>() {

					@Override
					public void onFailure(Throwable caught) {

					}

					@Override
					public void onSuccess(GetResult arg0) {
						contact = (Contact) arg0.getResult();
						refreshDisplay();
					}

				});

	}

	@Override
	protected void onPlaceRequest(PlaceRequest request) {

		String contactId = request.getParameter("contactId", null);
		if (contactId != null)
			getContact(contactId);
		else
			refreshDisplay();
	}

	@Override
	public void refreshDisplay() {
		if (contact != null) {
			display.getFirstName().setValue(contact.getFirstName());
			display.getLastName().setValue(contact.getLastName());
			display.getEmailAddress().setValue(contact.getEmailAddress());
		} else {
			display.getFirstName().setValue(null);
			display.getLastName().setValue(null);
			display.getEmailAddress().setValue(null);
		}

	}

	@Override
	public Place getPlace() {
		return PLACE;
	}

	@Override
	protected void onUnbind() {
		super.unbind();
	}

	@Override
	public void revealDisplay() {
	}

	@Override
	public void go(HasWidgets container) {
		container.clear();
	    container.add(display.asWidget());
	}

}
